home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / graphics / raymovi2.arc / MAIN.C < prev    next >
C/C++ Source or Header  |  1988-12-21  |  12KB  |  447 lines

  1. /* main.c 
  2.  *
  3.  *****************************************************************
  4.  *                                                               *
  5.  *                      basic ray tracing:                       *
  6.  *    spheres and a floor (reflection, refraction and diffuse)   *
  7.  *        programmer: friedrich knauss             *
  8.  *                       7-4-86 to 7-21-86                       *
  9.  *        ported to st: allen king 5/87, added:         *
  10.  *            limited color                 *
  11.  *            low rez display first             *
  12.  *            .25 to 16 rays per pixel          *
  13.  *            object definitions in file         *
  14.  *            multiple-frame movies             *
  15.  *            bouncing and gravity             *
  16.  *                                                               *
  17.  *****************************************************************/
  18.  
  19. #include <stdio.h>
  20. #include <math.h>
  21. #include <osbind.h>
  22. #include <gemdefs.h>
  23. #include "rtd.h"
  24. #define dprintf if (debug) printf
  25.  
  26. /* these definitions describe a window in the x-y plane
  27.    that the whole thing is viewd through. */
  28.  
  29. int XMIN, YMIN, XMAX, YMAX;
  30. float xmin, ymax;        /* floating pt versions */
  31.  
  32. wOnewSize(x,y, w,h)
  33. int x,y, w,h;
  34. {    XMIN = x;    YMIN = y;
  35.     XMAX = x+w+2;    YMAX = y+h+2;
  36. }
  37.  
  38. /* Nomenclature notes: 
  39.  *    1. <a>P<b> stands for "the number of <a>'s PER <b>
  40.  *    2. r stands for rays
  41.  *    3. p stands for pixels
  42.  *    4. s stands for either side of the screen
  43.  *    5. the suffix "Max" denotes the max number compiled into the program
  44.  *
  45.  * Note: these are linear (not area) conversions. A value of 2 rPp (rays PER
  46.  * pixel) is applied in both x and y directions to get an area (and more
  47.  * true to life) conversion of 4 (square) rays through each (square) pixel.
  48.  */
  49.     float rPp;            /* rays PER pixel (on a (linear) side)*/
  50. #   define rPpMax 4
  51.                 /* maximum rays PER pixel (ditto) */
  52.     int pPs;            /* pixels PER side (of screen) */
  53.     int rPs;            /* rays PER side (of screen) */
  54.     int rPsMax;            /* Max rays PER side (of screen) */
  55.  
  56. #define INC  1
  57. #define INCY  (1.25/rPpMax)
  58. #define INCX  (1.0/rPpMax)
  59.  
  60. int colorInd;            /* color index (1->b/w, 2->2tones, 3->3tones)*/
  61.  
  62. #define colors(r,g,b) 1000*(2*(r)+1)/16, 1000*(2*(g)+1)/16, 1000*(2*(b)+1)/16,
  63. int oldClut[16][3], trClut[][3] = 
  64. {
  65. #include "colors.h"
  66. 0};
  67.  
  68. struct 
  69. {    int (*pal)[][3];
  70.     int Navg;
  71. } cConfig[] = {{trClut, 16}, {trClut+16, 32}, {trClut+32, 43}};
  72.  
  73. FILE *fp, *fopen();
  74. char getline();
  75. char outname[6] = "pearl";
  76. int wHandle;
  77. int pxy_array[4];
  78.  
  79. #define Nball 15
  80. struct ball bl[Nball];
  81. int     level,
  82.         nob;
  83. struct vector vp;
  84. float gravity = 0.0, attraction = 0.0;
  85. int step, Step = 1000, bounce = 1;;
  86. int fr=0, frames=1;
  87.  
  88. int debug =0;
  89.  
  90. struct sphere   ls;
  91.  
  92. main ()
  93. {   static float    xco,
  94.                     yco, yup;
  95.     struct ray  rr;
  96.     int     h, i, j, k;
  97.     int c, cr, cg, cb;
  98.     int x0, y0, x1, y1, dx, dy, dmax, xMax, yMax;
  99.     double red, green, blue;                /* was int */
  100.     long ctr, BavgN;
  101.     float tmp;
  102.  
  103.     char str[200], *buf;
  104.     int Navg, *avg, *Bavg;
  105.  
  106.     rPp = 1.0;/* defaults: */
  107.     colorInd = 1;
  108.  
  109. /*    graf_mouse(M_OFF, 0L);/**/
  110.     printf("\033E");
  111.     do
  112.     {    printf("                RAYMOVI.PRG\n\n");
  113.     printf("Enter scene descriptor\nfilename: ");
  114.     if (getline(str, sizeof(str)) == '\003')
  115.         exit(0);
  116.     printf("\nreading file %s\n", str);
  117.     } while(scene_inz(str) == 0);
  118.  
  119.     printf("\033E");
  120.  
  121.     wHandle = w_open(0, "raymovi", 0);    /* open window (typeless, menueless) */
  122.     w_lClut(cConfig[colorInd-1].pal, oldClut);
  123.     v_hide_c(wHandle);
  124.  
  125.     xmin = XMIN;    ymax = YMAX;
  126.     dx = XMAX-XMIN;
  127.     dy = YMAX-YMIN;
  128.     if (rPp > 1.0001)
  129.     {    BavgN = (long)dx * dy * colorInd;
  130.     Bavg = Malloc(BavgN * sizeof(int));
  131.     if (Bavg == 0)
  132.     {   long l1;
  133.         printf("limited to 1 ray/pixel due to insufficient RAM\n");
  134.         if (rPp > 1.0)
  135.         rPp = 1.0;
  136.         for (l1=0; l1<200000; l1++);
  137.     }   
  138.     for (tmp = 1.0; rPp >= 1.0001; tmp *= 2.0, rPp /= 2.0);
  139.     }
  140.     else
  141.     for (tmp = 1.0; rPp < .5001; tmp /= 2.0, rPp *= 2.0);
  142.     rPp = tmp;
  143.     dmax = (dx>dy)? dx: dy;
  144.     for (i=dmax-1,       pPs=1;     i>0   ; i>>=1, pPs<<=1);
  145.     for (i=rPp*pPs-0.5,    rPs=1;   i>0   ; i>>=1, rPs<<=1);
  146.     rPsMax = rPpMax * pPs;
  147.     xMax = ((long)rPsMax*dx)/pPs;    yMax = ((long)rPsMax*dy)/pPs;
  148.  
  149.     for (; fr<=frames; fr++) 
  150.     {      int len, len1, p34, x, y, Elen, Ey;
  151. redraw:    
  152.     if (Bavg) for (avg = Bavg, ctr=0; ctr<BavgN; ctr++)
  153.         *avg++ = 0;
  154.     Navg = cConfig[colorInd-1].Navg;
  155.     ctr = 0;
  156.     for (len = rPsMax; len>= rPsMax/rPs; len /=2)
  157.     {   p34 = 3;
  158.         if (len>=rPpMax)
  159.         {    len1 = len/rPpMax - 1;
  160.         Elen = 0;
  161.         }else
  162.         {    len1 = 0;
  163.             Elen = rPpMax -1;
  164.         Navg *= 4;
  165.         }
  166.         for (y=0; y<yMax; y += len)
  167.         {    p34 = (p34 | 1) ^ 2;
  168.         if (Elen)
  169.             Ey = (((y + len)&Elen) == 0);
  170.         y0 = y/rPpMax;
  171.         y1 = y0 + YMIN;
  172.         pxy_array[1] = y1;
  173.         pxy_array[3] = y1 + len1;
  174.         yco = ymax - INCY*y;
  175.  
  176.         for (x=0; x<xMax; x += len)
  177.         {   if ((p34 ^=1) == 0 && ctr !=0)
  178.             continue;
  179.             ctr++;
  180.             x0 = x/rPpMax;
  181.             x1 = x0 + XMIN;
  182.             pxy_array[0] = x1;
  183.             pxy_array[2] = x1 + len1;
  184.             xco = xmin + INCX*x;
  185.  
  186.             /* define the ray through a pixel; find out value for that pixel */
  187.              mv (xco, yco, 0.0, &(rr.org));
  188.             sv (&(rr.dir), &(rr.org), &vp);
  189.             shade (&rr, &red, &green, &blue);   /* find out color */
  190.  
  191.             cb = blue;
  192.             cr = red;
  193.             cg = green;
  194.             if (Bavg)        /* compute sum for all rays */
  195.             {   register int *array;
  196.             array = Bavg + ((long)y0*dx+x0+1)*colorInd;
  197.             switch(colorInd)
  198.             { case 3:
  199.                 cg = *--array += cg;
  200.               case 2:
  201.                 cr = *--array += cr;
  202.               case 1:
  203.                 cb = *--array += cb;
  204.             }   }
  205.  
  206.             if (Elen==0 || Ey && ((x+len)&Elen) == 0 )
  207.             {    switch(colorInd)
  208.             { case 1:            /* white (and black): */
  209.                 c = (cb/Navg + 1) & 0xf;        /* white */
  210.                 break;
  211.               case 2:            /* white and red: */
  212.                 if (2*cr < 3*cb)
  213.                 c = cb/Navg+1 & 7;         /* white */
  214.                 else c = (cr/Navg & 7) + 8;        /* red */
  215.                 break;
  216.               case 3:            /* white, red, blue: */
  217.                 if (4*cr > 3*(cg+cb))
  218.                 {    c = cr/Navg % 6;        /* red */
  219.                 if (c) c += 5; /* red */
  220.                 else c = 1;
  221.                 }
  222.                 else if (4*cb > 3*(cr+cg))
  223.                 {    c = cb/Navg % 6;        /* blue */
  224.                 if (c) c += 10; /* red */
  225.                 else c = 1;
  226.                 }
  227.                 else c = (cg/Navg+1) % 6;         /* white */
  228.                 break;
  229.             }
  230.             dprintf("%d,%d,%d -> %d\n", cr, cg, cb, c);
  231.                 vsf_color(wHandle, c);    /*draw colored box*/
  232.             v_bar(wHandle, pxy_array);
  233.             }
  234.             if ((ctr&15)== 0 && kbd() == -1)
  235.             goto redraw;
  236.         }
  237.         sprintf(str, "%s%03d:     RAYMOVI.PRG     rpp=%05.3f", 
  238.             outname, fr, (float)ctr/((long)dx*dy));
  239.         di_header(1, str);
  240.     }   }     
  241.     sprintf(str, "%s%03d.pi1", outname, fr);
  242.     f_write(str, colorInd-1);
  243.  
  244.     movie(&bl, nob, step, Step, gravity, bounce, attraction);
  245.     write_ckpt("checkpt");
  246.     }
  247. exit:
  248.     w_lClut(oldClut, (long)0);
  249.     w_close();
  250. }
  251.  
  252. kbd()
  253. {    char key, fname[20];
  254.     int found_first = 0, fr1, rval=0;
  255.  
  256.     if (Cconis() == 0)
  257.         return(0);
  258.  
  259.     key = Cconin();
  260.     while (1)
  261.     {    sprintf(fname, "%s%03d.pi1", outname, fr);
  262.         switch(key)
  263.         {   case ('?'): case ('\0'):        /* help */
  264.             printf("\033E\n\n       RayMovi\n\
  265.             \nw - write \"%s\" from screen,\
  266.             \nr - read \"%s\" to screen,\
  267.             \np - play movie \"%sXXX.pi1\
  268.             \ne - exit\n\n", fname, fname, outname);
  269.             key = Cconin();
  270.             printf("\033E");
  271.             rval = -1;
  272.             break;
  273.             case ('D'):
  274.             debug = 1-debug;
  275.             return (rval);
  276.             case ('w'):
  277.             f_write(fname, colorInd-1);
  278.             return (rval);
  279.             case ('r'):    case ('p'):
  280.             fr1 = 1;
  281.             while (key == 'p' || key == 'r')
  282.             {    sprintf(fname,"%s%03d.pi1", outname, fr1++);
  283.                 if (f_read(fname, (long)0) <0)
  284.                 {    if (found_first)
  285.                     {    fr1 = 1;
  286.                         found_first = 0;
  287.                 }    }
  288.                 else
  289.                     found_first = 1;
  290.                 if (Cconis() != 0 || key == 'r' && found_first)
  291.                     key = Cconin();
  292.             }
  293.             rval = -1;
  294.             break;
  295.             case ('e'): case('\003'):
  296.             w_lClut(oldClut, (long)0);
  297.             w_close();
  298.             exit(0);
  299.             default:
  300.             return(rval);
  301. }    }    }
  302.  
  303. scene_inz(inz_file)
  304. char *inz_file;
  305. {   int h, i, j, k; char str[200], *buf;
  306.     if ((fp=fopen(inz_file, "r"))==0)
  307.     {    printf("can't open file '%s'\n", inz_file);
  308.     return(0);
  309.     }
  310.     j=0, h=0;
  311.     while (1)
  312.     {    int linenum;
  313.         buf = str;
  314.     for (k=0; (i = getc(fp)) != '\n' && i != EOF && ++k<sizeof(str)-1;)
  315.         *buf++ = i;
  316.     *buf = '\0';
  317.     linenum++;
  318.     print